home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
edit
/
jwpsrc.zip
/
SEARCH.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-03-31
|
45KB
|
1,538 lines
/* Copyright (C) Stephen Chung, 1991-1993. All rights reserved. */
#include "jwp.h"
#define EXPBLOCKSIZE 10
#define CURLYINDICATOR 0xff
typedef enum {
T_ERROR = 0, T_TEXT, T_ESCAPE,
T_SOFTRETURN, T_HARDRETURN, T_TAB,
T_MATCHALL, T_MATCHONE, T_MATCHKANJI, T_MATCHASCII, T_MATCHKANA,
T_COMMA, T_NOT, T_BOL, T_EOL, T_DASH,
T_OPENPAREN, T_CLOSEPAREN, T_OPENBRACKET, T_CLOSEBRACKET,
T_OPENCURLY, T_CLOSECURLY
} TOKEN;
static struct { char ascii; TOKEN token; } tokens[] = {
{ ',', T_COMMA },
{ '!', T_NOT },
{ '^', T_BOL },
{ '$', T_EOL },
{ '-', T_DASH },
{ '*', T_MATCHALL },
{ '?', T_MATCHONE },
{ '(', T_OPENPAREN },
{ ')', T_CLOSEPAREN },
{ '[', T_OPENBRACKET },
{ '[', T_OPENBRACKET },
{ ']', T_CLOSEBRACKET },
{ ']', T_CLOSEBRACKET },
{ '{', T_OPENCURLY },
{ '}', T_CLOSECURLY },
{ '\\', T_ESCAPE },
{ 0, T_ERROR }
};
static struct { char esc; TOKEN token; } escapes[] = {
{ 'n', T_SOFTRETURN }, /* \n */
{ 'p', T_HARDRETURN }, /* \p */
{ 't', T_TAB }, /* \t */
{ 'x', T_MATCHKANA }, /* \x */
{ 'k', T_MATCHKANJI }, /* \k */
{ 'a', T_MATCHASCII }, /* \a */
{ '\0', T_ERROR }
};
static char *CompileErrors[] = {
/* 0 */ "The character after the escape character is missing",
/* 1 */ "Special characters (\p, \n etc.) cannot be placed within square brackets",
/* 2 */ "You can only put a NOT symbol right AFTER the open bracket",
/* 3 */ "The closing bracket is missing",
/* 4 */ "You must enter something to search for",
/* 5 */ "The range is not correct",
/* 6 */ "There must be character(s) inside a pair of brackets",
/* 7 */ "Curly brackets must enclose the digit 1 - 9",
/* 8 */ "",
/* 9 */ "Internal Error. Life is tough."
};
typedef struct RegexStruct {
TOKEN action;
LONG data;
POSITION startpos, endpos;
struct RegexStruct far *prev, far *next;
} REGEX;
static REGEX far *Expression = NULL;
static KANJI far *ExpText = NULL;
static KANJI far *ReplaceExp = NULL;
static KANJI far *ReplaceText = NULL;
static struct {
int IgnoreCase:1;
int Regex:1;
int JASCII:1;
int WrapAround:1;
int WholeFile:1;
int NoConfirm:1;
} SearchOptions = { 1, 0, 1, 0, 0, 0 };
BOOL FAR PASCAL SearchProc (HWND, WORD, WORD, LONG);
BOOL FAR PASCAL ReplaceProc (HWND, WORD, WORD, LONG);
BOOL FAR PASCAL ReplaceDlgProc (HWND, WORD, WORD, LONG);
BOOL FAR PASCAL EditReplacementProc (HWND, WORD, WORD, LONG);
static KANJI far *Replacement = NULL;
static int FindToken (KANJI token)
{
int i;
char ch;
token &= 0x7f7f;
if (ISKANJI(token)) {
ch = LOBYTE(TranslateJAscii(token, TRUE));
if (!ch) return (-1);
} else {
ch = LOBYTE(token);
}
for (i = 0; tokens[i].token != T_ERROR; i++) {
if (tokens[i].ascii == ch) return (i);
}
return (-1);
}
static int FindEscape (KANJI escape)
{
int i;
if ('A' <= escape && escape <= 'Z') escape += 32;
for (i = 0; escapes[i].token != T_ERROR; i++) {
if (escapes[i].esc == escape) return (i);
}
return (-1);
}
static void FreeRegex (REGEX far *rp)
{
REGEX far *rp2;
if (rp == NULL) return;
for (; rp != NULL; ) {
switch (rp->action) {
case T_TEXT:
FreeBlock(rp->data);
break;
case T_NOT:
case T_OPENBRACKET:
case T_OPENPAREN:
case T_OPENCURLY:
FreeRegex((REGEX far *) rp->data);
break;
default:
break;
}
rp2 = rp->next;
FreeBlock(rp);
rp = rp2;
}
}
#define RETURN_WITH_ERROR(x,y) { FreeRegex(RegexChain); RegexChain = NULL; *OutStr = InStr + (x); *ErrorNum = (y); return (NULL); }
static REGEX far *CompileBracketedString (UNIT far *InStr, UNIT far **OutStr, int *ErrorNum, BOOL not)
{
int i, j, k, errornum;
KANJI kch;
KANJI far *kp;
REGEX far *RegexChain = NULL, far *rp;
for (i = 0; InStr[i].kanji; i++) {
kch = InStr[i].kanji;
j = FindToken(kch);
if (j >= 0) {
switch (tokens[j].token) {
case T_CLOSEBRACKET:
if (RegexChain == NULL) RETURN_WITH_ERROR(i, 6);
*OutStr = InStr + i;
return (RegexChain);
case T_ESCAPE:
kch = InStr[++i].kanji;
if (!kch) RETURN_WITH_ERROR(i, 0);
k = FindEscape(kch);
if (k >= 0) RETURN_WITH_ERROR(i, 1);
break;
case T_NOT: {
REGEX far *rpx;
UNIT far *up;
if (!not) RETURN_WITH_ERROR(i, 2);
rpx = CompileBracketedString(InStr + i + 1, &up, &errornum, FALSE);
i = up - InStr;
if (rpx == NULL) RETURN_WITH_ERROR(i, errornum);
/* Adds to it */
if (RegexChain == NULL) {
RegexChain = rp = StructAlloc(REGEX);
rp->action = T_NOT;
rp->data = (LONG) rpx;
rp->next = rp->prev = NULL;
} else {
rp->next = StructAlloc(REGEX);
rp->next->prev = rp;
rp = rp->next;
rp->next = NULL;
rp->action = T_NOT;
rp->data = (LONG) rpx;
}
*OutStr = up;
return (RegexChain); /* Success! */
}
}
}
not = FALSE;
if (j < 0 || tokens[j].token != T_DASH) {
j = FindToken(InStr[i+1].kanji);
} else {
kch = 0;
i--; /* Because it is i += 2 later on */
goto ItIsADash;
}
if (j >= 0) {
switch (tokens[j].token) {
ItIsADash:
case T_DASH: {
KANJI start, stop;
start = kch;
i += 2;
stop = InStr[i].kanji;
if (!stop) RETURN_WITH_ERROR(i, 3);
j = FindToken(stop);
if (j >= 0 && tokens[j].token == T_CLOSEBRACKET) {
stop = 0xffff; /* Maximum value */
i--;
} else if (j >= 0 && tokens[j].token == T_ESCAPE) {
stop = InStr[++i].kanji;
if (!stop) RETURN_WITH_ERROR(i, 3);
k = FindEscape(stop);
if (k >= 0) RETURN_WITH_ERROR(i, 1);
}
//if (ISKANJI(start) && !ISKANJI(stop)) RETURN_WITH_ERROR(i, ?);
//if (!ISKANJI(start) && ISKANJI(stop)) RETURN_WITH_ERROR(i, ?);
if (start > stop) RETURN_WITH_ERROR(i, 5);
if (start == stop) {
kch = start;
goto StraightText;
}
/* Adds to it */
if (RegexChain == NULL) {
RegexChain = rp = StructAlloc(REGEX);
rp->action = T_DASH;
rp->data = MAKELONG(start,stop);
rp->next = rp->prev = NULL;
} else {
rp->next = StructAlloc(REGEX);
rp->next->prev = rp;
rp = rp->next;
rp->next = NULL;
rp->action = T_DASH;
rp->data = MAKELONG(start,stop);
}
continue;
}
}
}
/* Now, just a normal character */
StraightText:
if (RegexChain == NULL) {
RegexChain = rp = StructAlloc(REGEX);